package com.fengwenyi.studymybatisxml;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;
import java.io.IOException;

/**
 * @author Erwin Feng
 * @since 2021-03-20
 */
public class XPathTest {

    public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException {
        DocumentBuilderFactory documentBuilderFactory =
                DocumentBuilderFactory.newInstance();

        // 开启验证
        documentBuilderFactory.setValidating(false); // 加验证，报错 // error:文档根元素 "inventory" 必须匹配 DOCTYPE 根 "null"。
        documentBuilderFactory.setNamespaceAware(false);
        documentBuilderFactory.setIgnoringComments(true);
        documentBuilderFactory.setIgnoringElementContentWhitespace(false);
        documentBuilderFactory.setCoalescing(false);
        documentBuilderFactory.setExpandEntityReferences(true);


        // 创建 DocumentBuilder
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

        // 设置异常处理对象
        documentBuilder.setErrorHandler(new ErrorHandler() {
            @Override
            public void warning(SAXParseException exception) throws SAXException {
                System.out.println("warn:" + exception.getMessage());
            }

            @Override
            public void error(SAXParseException exception) throws SAXException {
                System.out.println("error:" + exception.getMessage());
            }

            @Override
            public void fatalError(SAXParseException exception) throws SAXException {
                System.out.println("fatalError:" + exception.getMessage());
            }
        });

        // 将文档添加到一个 Document 对象中
        Document document = documentBuilder.parse("src/main/resources/inventory.xml");
        // 创建 XPathFactory
        XPathFactory xPathFactory = XPathFactory.newInstance();
        // 创建 XPath 对象
        XPath xPath = xPathFactory.newXPath();
        // 编译 XPath 表达式
        XPathExpression xPathExpression = xPath.compile("//book[author='Neal Stephenson']/title/text()");
        Object result = xPathExpression.evaluate(document, XPathConstants.NODESET);
        System.out.println("查询作者为Neal Stephenson的图书的标题：");
        NodeList nodeList = (NodeList) result;
        for (int i = 0; i < nodeList.getLength(); i++) {
            System.out.println("《" + nodeList.item(i).getNodeValue() + "》");
        }

        System.out.println();

        System.out.println("查询1997年之后的图书的标题：");

        nodeList = (NodeList) xPath.evaluate("//book[@year > 1997]/title/text()", document, XPathConstants.NODESET);
        for (int i = 0; i < nodeList.getLength(); i++) {
            System.out.println("《" + nodeList.item(i).getNodeValue() + "》");
        }

        System.out.println();

        System.out.println("查询1997年之后的图书的属性和标题：");

        nodeList = (NodeList) xPath.evaluate("//book[@year > 1997]/@* | //book[@year > 1997]/title/text()", document, XPathConstants.NODESET);
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node item = nodeList.item(i);
            if (item.getNodeName().equalsIgnoreCase("year")) {
                System.out.print(item.getNodeValue() + "----");
            } else {
                System.out.println("《" + nodeList.item(i).getNodeValue() + "》");
            }
        }

    }

}
